﻿using System;
using System.Collections.Generic;
using System.Linq;
using SmartAssembly;
using Utilities.DynamicValues;

namespace AbstractBugTracker
{
    public sealed class ExceptionReportHasher : IExceptionReportHasher
    {
        private readonly IDynamicValueCompiler<Func<Report, string>> m_DynamicValueCompiler;
        private readonly IDictionary<string, Func<Report, string>> m_ExceptionTypeNameToHasher;

        public ExceptionReportHasher(IDynamicValueCompiler<Func<Report, string>> dynamicValueCompiler, IEnumerable<KeyValuePair<string, string>> exceptionTypeNameToHasherSourceCode)
        {
            m_DynamicValueCompiler = dynamicValueCompiler;
            m_ExceptionTypeNameToHasher = new Dictionary<string, Func<Report, string>>();
            foreach (KeyValuePair<string, string> pair in exceptionTypeNameToHasherSourceCode)
            {
                string exceptionTypeName = pair.Key;
                string hasherSourceCode = pair.Value;
                Func<Report, string> hasher = m_DynamicValueCompiler.GetOrCompile(hasherSourceCode, typeof(Enumerable));
                m_ExceptionTypeNameToHasher.Add(exceptionTypeName, hasher);
            }
        }

        public string GetExceptionReportHash(Report report)
        {
            Func<Report, string> hasher;
            if (m_ExceptionTypeNameToHasher.TryGetValue(report.ExceptionTypeName, out hasher))
            {
                string hash = hasher(report);
                if (hash == null)
                {
                    throw new Exception("hasher must not return null hash");
                }
                return hash;
            }
            return null;
        }
    }
}